﻿#region Copyright 
/*-------------------------------------------------------------------------
* 命名空间名称/文件名:    SSPivot.Admin.Core.Service.sys.User/SysUserServiceImpl 
* CLR版本:     4.0.30319.42000
* 机器名称:    DESKTOP-NHMLO8A
* 功 能：       N/A
* 类 名：       SysUserServiceImpl
* 创建时间：  2025/6/4 16:44:08
* 版本号：      v1.0
* 创建人:        xulong
*-------------------------------------------------------------------------*/
#endregion
using DotNetCore.CAP.Dashboard;
using DotNetCore.CAP;
using MapsterMapper; 
using Microsoft.Extensions.Options;
using SSPivot.Admin.Core.DbModel.sys;
using SSPivot.Admin.Core.Service.Dto;
using SSPivot.Admin.Core.Service.sys.Org.Dto;
using SSPivot.Admin.Core.Service.sys.Role.Dto;
using SSPivot.Admin.Core.Service.sys.User.Dto;
using SSPivot.AspNetCore.Abstractions.User;
using SSPivot.AspNetCore.Services;
using SSPivot.Common.Helpers;
using SSPivot.Common;
using SSPivot.IM;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;
using SSPivot.Admin.Core.Repository;
using Mapster;
using Microsoft.EntityFrameworkCore;
using SSPivot.Admin.Core.Service.communal.Account.Dto;
using SSPivot.AspNetCore;

namespace SSPivot.Admin.Core.Service.sys.User
{
    /// <summary>
    /// 用户服务
    /// </summary>
    public class SysUserServiceImpl : ApplicationService, ISysUserService
    {
        #region 接口注入
        public ISSPivotRepository<sys_user> SysUserRep { get; set; }
        public ISSPivotRepository<sys_user_org> SysUserOrgRep { get; set; }
        public ISSPivotRepository<sys_user_role> SysUserRoleRep { get; set; } 
        public Lazy<ISSPivotRepository<sys_role>> SysRoleRepLazy { get; set; }
        public Lazy<ISSPivotRepository<sys_role_permission>> SysRolePermissionRepLazy { get; set; }
        public Lazy<ISSPivotRepository<sys_role_org>> SysRoleOrgRepLazy { get; set; }  
        public Lazy<ISSPivotRepository<sys_org>> SysOrgRepLazy { get; set; } 
        public Lazy<ISSPivotRepository<sys_permission>> SysPermissionRepLazy { get; set; }   
        private readonly ImConfig ImConfig; 
        public SysUserServiceImpl( ImConfig imConfig)
        { 
            ImConfig = imConfig;
        }
        #endregion

        #region 服务

        /// <summary>
        /// 查询用户
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public async Task<UserGetDto> GetAsync(long id)
        {
            var data = await SysUserRep.GetAsync(id);
            var result = data.Adapt<UserGetDto>();
            var roleIds = await SysUserRoleRep.QueryNoTracking(e => e.UserId == result.Id).Select(e => e.RoleId).ToListAsync();
            result.Roles = await SysRoleRepLazy.Value.QueryNoTracking(e => roleIds.Contains(e.Id)).Select(e => new UserGetRoleDto()
            {
                Id = e.Id,
                Name = e.Name
            }).ToListAsync();
            var orgIds = await SysUserOrgRep.QueryNoTracking(e => e.UserId == result.Id).Select(e => e.OrgId).ToListAsync();
            result.Orgs = (await SysOrgRepLazy.Value.QueryNoTracking(e => orgIds.Contains(e.Id)).ToListAsync()).Adapt<List<SysOrgDto>>();
            result.ManagerUser = (await SysUserRep.GetAsync(result.ManagerUserId)).Adapt<SysUserDto>();
            
            return result;
        }

        /// <summary>
        /// 查询分页
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>   
        public async Task<(List<UserGetPageDto>, PageResult)> QueryPageAsync(QuerySysUserRequset model, PageResult page)
        {
            var where = await this.BuildSearch(model);
            where = where.And(e => e.Type == UserType.Member);
            var data = await SysUserRep.Query(where, this.BuildSort(model), page).ToListAsync();


            var result = new List<UserGetPageDto>();
            var manageUserIds = new List<long>();
            if (model.OrgId.HasValue && model.OrgId > 0)
                manageUserIds = await SysUserOrgRep.QueryNoTracking(e => e.OrgId == model.OrgId && e.IsManager == true).Select(e => e.UserId).ToListAsync();
            //用户在线离线查询
            var onLineUserIds = new List<long>();
            if (ImConfig.Enabled)
            {
                onLineUserIds = ImHelper.GetClientListByOnline().ToList();
            }
            foreach (var item in result)
            {
                var dto = item.Adapt<UserGetPageDto>();
                var roleIds = (await SysUserRoleRep.QueryNoTracking(e => e.UserId == item.Id).Select(e => e.RoleId).ToListAsync());
                dto.Roles = (await SysRoleRepLazy.Value.QueryNoTracking(e => roleIds.Contains(e.Id)).ToListAsync()).Adapt<List<SysRoleDto>>();
                if (manageUserIds != null && manageUserIds.Count > 0 && manageUserIds.Contains(item.Id))
                    dto.IsManager = true;
                //用户在线离线查询
                if (onLineUserIds != null && onLineUserIds?.Count > 0 && onLineUserIds.Contains(item.Id))
                    dto.Online = true;

            }
            return (result, page);
        }

        /// <summary>
        /// 查询登录用户信息
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns> 
        public async Task<AuthLoginResultDto> GetLoginUserAsync(long id)
        {
            var data = await SysUserRep.GetAsync(id);
            var result = data.Adapt<AuthLoginResultDto>();
            
            return result;
        }

        /// <summary>
        /// 获得数据权限
        /// </summary>
        /// <param name="apiPath"></param>
        /// <returns></returns> 
        public async Task<DataPermissionDto> GetDataPermissionAsync(string? apiPath)
        {
            if (!(User?.Id > 0))
            {
                return null;
            }
            return await Cache.GetOrAddAsync<DataPermissionDto>(SSPivot.AspNetCore.GlobalConfigAspNetCore.CacheKeys.GetDataPermissionKey(User.Id.Value, apiPath), async () =>
            {
                var orgId = await SysUserRep.QueryNoTracking(e => e.Id == User.Id).Select(e => e.OrgId).FirstOrDefaultAsync();
                if (orgId == 0) return null;

                var roleIds = await SysUserRoleRep.Query(e => e.UserId == User.Id).Select(e => e.RoleId).ToListAsync();
                //if (apiPath.IsNotNullOrEmpty())
                //{
                //    var apiIds = await SysApiRepLazy.Value.QueryNoTracking(e => e.Path == apiPath).Select(e => e.Id).ToListAsync();
                //    var permissionIds = await SysPermissionApiRepLazy.Value.QueryNoTracking(e => apiIds.Contains(e.ApiId)).Select(e => e.PermissionId).ToListAsync();
                //    var rids = await SysRolePermissionRepLazy.Value.QueryNoTracking(e => permissionIds.Contains(e.PermissionId)).Select(e => e.RoleId).ToListAsync();
                //    roleIds = roleIds.Where(e => rids.Contains(e)).ToList();
                //}
                var roles = await SysRoleRepLazy.Value.QueryNoTracking(e => roleIds.Contains(e.Id)).Select(e => new
                {
                    e.Id,
                    e.DataScope
                }).ToListAsync();
                //数据范围
                DataScope dataScope = DataScope.Self;
                var customRoleIds = new List<long>();
                roles?.ForEach(e =>
                {
                    if (e.DataScope == DataScope.Custom) customRoleIds.Add(e.Id);
                    else if (e.DataScope == dataScope) dataScope = e.DataScope;
                });
                //部门列表
                var orgIds = new List<long>();
                if (dataScope != DataScope.All)
                {
                    //本部门
                    if (dataScope == DataScope.Dept) orgIds.Add(orgId);
                    else if (dataScope == DataScope.DeptWithChild)
                    {
                        orgIds = await SysOrgRepLazy.Value.Query(e => e.ParentIds.Contains(orgId.ToString())).Select(e => e.Id).ToListAsync();
                    }
                    //指定部门
                    if (customRoleIds.Count > 0)
                    {
                        if (dataScope == DataScope.Self) dataScope = DataScope.Custom;
                        var customRoleOrgIds = await SysRoleOrgRepLazy.Value.QueryNoTracking(e => customRoleIds.Contains(e.RoleId)).Select(e => e.OrgId).ToListAsync();
                        orgIds = orgIds.Concat(customRoleOrgIds).ToList();
                    }
                }
                var orgName = await SysRoleRepLazy.Value.QueryNoTracking(e => e.Id == orgId).Select(e => e.Name).FirstOrDefaultAsync();

                return new DataPermissionDto()
                {
                    OrgName = orgName,
                    OrgId = orgId,
                    OrgIds = orgIds,
                    DataScope = (User.PlatformAdmin || User.TenantAdmin) ? DataScope.All : dataScope
                };
            });
        }

        /// <summary>
        /// 查询用户基本信息
        /// </summary>
        /// <returns></returns> 
        public async Task<UserGetBasicDto> GetBasicAsync()
        {
            if (!(User?.Id > 0))
            {
                throw ServiceResult.Exception("未登录");
            }

            var user = await SysUserRep.GetAsync(User.Id);

            if (user == null)
            {
                throw ServiceResult.Exception("用户不存在");
            }
            var result = user.Adapt<UserGetBasicDto>();
            user.Mobile = user.Mobile.MaskMobile();
            user.Email = user.Email.MaskEmail();

            return result;
        }

        /// <summary>
        /// 查询用户权限信息
        /// </summary>
        /// <returns></returns>
        public async Task<UserPermissionDto> GetPermissionAsync()
        {
            var result = await Cache.GetOrAddAsync<UserPermissionDto>(SSPivot.AspNetCore.GlobalConfigAspNetCore.CacheKeys.GetUserPermissionKey(User.Id.Value), async () =>
            {
                var output = new UserPermissionDto();
                if (User.Type == UserType.DefaultUser || User.Type == UserType.Member) return output;
                //if (User.TenantAdmin)
                //{
                //    //租户接口
                //    var permissionIds = await SysTenantPermissionRepLazy.Value.QueryNoTracking(e => e.TenantId == User.TenantId).Select(e => e.PermissionId).ToListAsync();
                //    var apiIds = await SysPermissionApiRepLazy.Value.QueryNoTracking(e => permissionIds.Contains(e.PermissionId)).Select(e => e.ApiId).ToListAsync();
                //    var tenantApis = await SysApiRepLazy.Value.QueryNoTracking(e => apiIds.Contains(e.Id)).Select(e => new UserPermissionDto.ApiModel
                //    {
                //        Path = e.Path,
                //        HttpMethods = e.HttpMethods
                //    }).ToListAsync();

                //    //租户权限点编码 
                //    var tenantCodes = await SysPermissionRepLazy.Value.QueryNoTracking(e => permissionIds.Contains(e.Id) && e.Type == PermissionType.Dot && e.Code != null && e.Code != "").Select(e => e.Code).ToListAsync();

                //    //套餐接口
                //    var pkgIds = await SysTenantPkgRepLazy.Value.QueryNoTracking(e => e.TenantId == User.TenantId).Select(e => e.PkgId).ToListAsync();
                //    var pkgPermissionIds = await SysPkgPermissionRepLazy.Value.QueryNoTracking(e => pkgIds.Contains(e.PkgId)).Select(e => e.PermissionId).ToListAsync();
                //    var pkgApiIds = await SysPermissionApiRepLazy.Value.QueryNoTracking(e => pkgPermissionIds.Contains(e.PermissionId)).Select(e => e.ApiId).ToListAsync();
                //    var pkgApis = await SysApiRepLazy.Value.QueryNoTracking(e => pkgApiIds.Contains(e.Id)).Select(e => new UserPermissionDto.ApiModel
                //    {
                //        Path = e.Path,
                //        HttpMethods = e.HttpMethods
                //    }).ToListAsync();

                //    //套餐权限点编码
                //    var tenantPkgIds = await SysTenantPkgRepLazy.Value.QueryNoTracking(e => e.TenantId == User.TenantId).Select(e => e.PkgId).ToListAsync();
                //    var tenantPermissionIds = await SysPkgPermissionRepLazy.Value.QueryNoTracking(e => tenantPkgIds.Contains(e.PkgId)).Select(e => e.PermissionId).ToListAsync();
                //    var pkgCodes = await SysPermissionRepLazy.Value.QueryNoTracking(e => tenantPermissionIds.Contains(e.Id) && e.Type == PermissionType.Dot && e.Code != null && e.Code != "").Select(e => e.Code).ToListAsync();

                //    output.Apis = tenantApis.Union(pkgApis).Distinct().ToList();

                //    output.Codes = tenantCodes.Union(pkgCodes).Distinct().ToList();

                //    return output;
                //}

                {
                    //角色接口
                    var roleIds = await SysUserRoleRep.QueryNoTracking(e => e.UserId == User.Id).Select(e => e.RoleId).ToListAsync();
                    var permissionIds = await SysRolePermissionRepLazy.Value.QueryNoTracking(e => roleIds.Contains(e.RoleId)).Select(e => e.PermissionId).ToListAsync();
                    //var apiIds = await SysPermissionApiRepLazy.Value.QueryNoTracking(e => permissionIds.Contains(e.PermissionId)).Select(e => e.ApiId).ToListAsync();
                    //var apis = await SysApiRepLazy.Value.QueryNoTracking(e => apiIds.Contains(e.Id)).Select(e => new UserPermissionDto.ApiModel()
                    //{
                    //    Path = e.Path,
                    //    HttpMethods = e.HttpMethods
                    //}).ToListAsync();

                    var codes = await SysPermissionRepLazy.Value.QueryNoTracking(e => permissionIds.Contains(e.Id) && e.Type == PermissionType.Dot && e.Code != null && e.Code != "").Select(e => e.Code).ToListAsync();

                    output.Codes = output.Codes.Distinct().ToList();

                }
                return output;
            });
            return result;
        }

        /// <summary>
        /// 新增用户
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        public virtual async Task<long> AddAsync(SysUserAddDto model)
        {
            //检查密码
            if (model.Password.IsNull())
            {
                model.Password = ConfigHelper.GetAppSetting("DefaultPassword");//.DefaultPassword;
            }
            //验证密码
            ServiceUtility.CheckPassword(model.Password); 


            Expression<Func<sys_user, bool>> where = (a => a.Account == model.Account);
            if (model.Mobile.IsNotNullOrWhiteSpace())
                where = where.And(e => e.Mobile == model.Mobile);
            if (model.Email.IsNotNullOrWhiteSpace())
                where = where.And(e => e.Email == model.Email);

            var existsUser = await SysUserRep.Query(where).Select(e => new
            {
                e.Account,
                e.Mobile,
                e.Email
            }).FirstOrDefaultAsync();

            if (existsUser != null)
            {
                if (existsUser.Account == model.Account)
                {
                    throw ServiceResult.Exception("账号已存在");
                }

                if (model.Mobile.IsNotNullOrWhiteSpace() && existsUser.Mobile == model.Mobile)
                {
                    throw ServiceResult.Exception("手机号已存在");
                }

                if (model.Email.IsNotNullOrWhiteSpace() && existsUser.Email == model.Email)
                {
                    throw ServiceResult.Exception("邮箱已存在");
                }
            }

            // 用户信息
            var entity = Mapper.Map<sys_user>(model);
            entity.Id = IdGeneratorHelper.IdSnowflake();
            entity.Type = UserType.DefaultUser;
            entity.Password = EncryptHelper.AesEcbEncryptToHex(model.Password, GlobalConfig.PASSWORD_ENCRYPT_KEY);

            var user = await SysUserRep.AddAsync(entity);
            var userId = user.Id;

            //用户角色
            if (model.RoleIds != null && model.RoleIds.Any())
            {
                var roles = model.RoleIds.Select(roleId => new sys_user_role
                {
                    UserId = userId,
                    RoleId = roleId
                }).ToList();
                await SysUserRoleRep.AddRangeAsync(roles);
            }
             
            //所属部门
            if (model.OrgIds != null && model.OrgIds.Any())
            {
                var orgs = model.OrgIds.Select(orgId => new sys_user_org
                {
                    UserId = userId,
                    OrgId = orgId
                }).ToList();
                await SysUserOrgRep.AddRangeAsync(orgs);
            }

            return userId;
        }

        /// <summary>
        /// 修改用户
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns> 
        public virtual async Task UpdateAsync(SysUserAddDto model)
        {
            if (model.Id == model.ManagerUserId)
            {
                throw ServiceResult.Exception("直属主管不能是自己");
            }



            Expression<Func<sys_user, bool>> where = (a => a.Account == model.Account && a.Id != model.Id);
            if (model.Mobile.IsNotNullOrWhiteSpace())
                where = where.And(e => e.Mobile == model.Mobile);
            if (model.Email.IsNotNullOrWhiteSpace())
                where = where.And(e => e.Email == model.Email);



            var existsUser = await SysUserRep.Query(where).Select(e => new
            {
                e.Account,
                e.Mobile,
                e.Email
            }).FirstOrDefaultAsync();

            if (existsUser != null)
            {
                if (existsUser.Account == model.Account)
                {
                    throw ServiceResult.Exception("账号已存在");
                }

                if (model.Mobile.IsNotNullOrWhiteSpace() && existsUser.Mobile == model.Mobile)
                {
                    throw ServiceResult.Exception("手机号已存在");
                }

                if (model.Email.IsNotNullOrWhiteSpace() && existsUser.Email == model.Email)
                {
                    throw ServiceResult.Exception("邮箱已存在");
                }
            }

            var user = await SysUserRep.GetAsync(model.Id);
            if (!(user?.Id > 0))
            {
                throw ServiceResult.Exception("用户不存在");
            }

            Mapper.Map(model, user);
            await SysUserRep.UpdateAsync(user);

            var userId = user.Id;

            // 用户角色
            await SysUserRoleRep.Query(a => a.UserId == userId).ExecuteDeleteAsync();
            if (model.RoleIds != null && model.RoleIds.Any())
            {
                var roles = model.RoleIds.Select(roleId => new sys_user_role
                {
                    UserId = userId,
                    RoleId = roleId
                }).ToList();
                await SysUserRoleRep.AddRangeAsync(roles);
            }
             
            await Cache.RemoveAsync(GlobalConfig.CacheKeys.GetDataPermissionPattern(userId));
        }

        /// <summary>
        /// 新增会员
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        public virtual async Task<long> AddMemberAsync(SysUserAddMemberDto model)
        {
            if (model.Password.IsNull())
            {
                model.Password = ConfigHelper.GetAppSetting("DefaultPassword");// AppConfig.DefaultPassword;
            }
            //验证密码
            ServiceUtility.CheckPassword(model.Password);



            Expression<Func<sys_user, bool>> where = (a => a.Account == model.Account);
            if (model.Mobile.IsNotNullOrWhiteSpace())
                where = where.And(e => e.Mobile == model.Mobile);
            if (model.Email.IsNotNullOrWhiteSpace())
                where = where.And(e => e.Email == model.Email);

            var existsUser = await SysUserRep.Query(where).Select(e => new
            {
                e.Account,
                e.Mobile,
                e.Email
            }).FirstOrDefaultAsync();

            if (existsUser != null)
            {
                if (existsUser.Account == model.Account)
                {
                    throw ServiceResult.Exception("账号已存在");
                }

                if (model.Mobile.IsNotNullOrWhiteSpace() && existsUser.Mobile == model.Mobile)
                {
                    throw ServiceResult.Exception("手机号已存在");
                }

                if (model.Email.IsNotNullOrWhiteSpace() && existsUser.Email == model.Email)
                {
                    throw ServiceResult.Exception("邮箱已存在");
                }
            }

            // 用户信息
            var entity = Mapper.Map<sys_user>(model);
            entity.Type = UserType.Member;
            entity.Password = EncryptHelper.AesEcbEncryptToHex(entity.Password, GlobalConfig.PASSWORD_ENCRYPT_KEY);

            var user = await SysUserRep.AddAsync(entity);

            return user.Id;
        }

        /// <summary>
        /// 修改会员
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns> 
        public virtual async Task UpdateMemberAsync(SysUserAddMemberDto model)
        {
            Expression<Func<sys_user, bool>> where = (a => a.Account == model.Account && a.Id != model.Id);
            if (model.Mobile.IsNotNullOrWhiteSpace())
                where = where.And(e => e.Mobile == model.Mobile);
            if (model.Email.IsNotNullOrWhiteSpace())
                where = where.And(e => e.Email == model.Email);

            var existsUser = await SysUserRep.Query(where).Select(e => new
            {
                e.Account,
                e.Mobile,
                e.Email
            }).FirstOrDefaultAsync();


            if (existsUser != null)
            {
                if (existsUser.Account == model.Account)
                {
                    throw ServiceResult.Exception("账号已存在");
                }

                if (model.Mobile.IsNotNullOrWhiteSpace() && existsUser.Mobile == model.Mobile)
                {
                    throw ServiceResult.Exception("手机号已存在");
                }

                if (model.Email.IsNotNullOrWhiteSpace() && existsUser.Email == model.Email)
                {
                    throw ServiceResult.Exception("邮箱已存在");
                }
            }

            var user = await SysUserRep.GetAsync(model.Id);
            if (!(user?.Id > 0))
            {
                throw ServiceResult.Exception("用户不存在");
            }

            Mapper.Map(model, user);
            await SysUserRep.UpdateAsync(user);
        }

        /// <summary>
        /// 更新用户基本信息
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns> 
        public async Task UpdateBasicAsync(SysUserUpdateBasicDto model)
        {
            var entity = await SysUserRep.GetAsync(User.Id);
            entity = Mapper.Map(model, entity);
            await SysUserRep.UpdateAsync(entity);
        }

        /// <summary>
        /// 修改用户密码
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns> 
        public async Task ChangePasswordAsync(SysUserChangePasswordDto model)
        {
            if (model.ConfirmPassword != model.NewPassword)
            {
                throw ServiceResult.Exception("新密码和确认密码不一致");
            }

            //验证密码
            ServiceUtility.CheckPassword(model.NewPassword);

            var entity = await SysUserRep.GetAsync(User.Id);
            var oldPassword = EncryptHelper.AesEcbEncryptToHex(model.OldPassword, GlobalConfig.PASSWORD_ENCRYPT_KEY);
            if (oldPassword != entity.Password)
            {
                throw ServiceResult.Exception("旧密码不正确");
            }
            entity.Password = EncryptHelper.AesEcbEncryptToHex(model.NewPassword, GlobalConfig.PASSWORD_ENCRYPT_KEY);

            await SysUserRep.UpdateAsync(entity);
        }

        /// <summary>
        /// 重置密码
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        public async Task<string> ResetPasswordAsync(UserResetPasswordDto model)
        {
            var password = model.Password;
            if (password.IsNullOrWhiteSpace())
            {
                password = ConfigHelper.GetAppSetting("DefaultPassword");
            }
            //验证密码
            ServiceUtility.CheckPassword(model.Password);
           
            password = EncryptHelper.AesEcbEncryptToHex(password, GlobalConfig.PASSWORD_ENCRYPT_KEY);
            await SysUserRep.Query(e => e.Id == model.Id).UpdateFromQueryAsync(e => new sys_user()
            {
                Password = password
            });

            return password;
        }

        /// <summary>
        /// 设置主管
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        public async Task SetManagerAsync(UserSetManagerDto model)
        {
            await SysUserOrgRep.Query(a => a.UserId == model.UserId && a.OrgId == model.OrgId)
                .UpdateFromQueryAsync(e => new sys_user_org
                {
                    IsManager = model.IsManager
                });
        }

        /// <summary>
        /// 设置启用
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        public async Task SetEnableAsync(SetEnabledDto model)
        {
            var type = await SysUserRep.QueryNoTracking(e => e.Id == model.Id).Select(e => e.Type).FirstOrDefaultAsync();

            if (type == UserType.PlatformAdmin)
            {
                throw ServiceResult.Exception("平台管理员禁止禁用");
            }
            if (type == UserType.TenantAdmin)
            {
                throw ServiceResult.Exception("企业管理员禁止禁用");
            }
            await SysUserRep.Query(e => e.Id == model.Id).UpdateFromQueryAsync(e => new sys_user()
            {
                Enabled = model.IsEnabled
            });
        }

        /// <summary>
        /// 批量设置部门
        /// </summary>
        /// <returns></returns> 
        public virtual async Task BatchSetOrgAsync(UserBatchSetOrgDto model)
        {
            //主属部门
            await SysUserRep.Query(e => model.UserIds.Contains(e.Id)).UpdateFromQueryAsync(e => new sys_user
            {
                OrgId = model.OrgId,
                LastModifier = User.Account,
                LastModifierId = User.Id,
                LastModifyTime = DateTime.Now
            });

            //所属部门
            var orgIds = await SysUserOrgRep.QueryNoTracking(e => model.UserIds.Contains(e.UserId)).Select(e => e.OrgId).ToListAsync();

            var insertOrgIds = model.OrgIds.Except(orgIds);

            var deleteOrgIds = orgIds.Except(model.OrgIds).ToArray();
            if (deleteOrgIds != null && deleteOrgIds.Any())
            {
                await SysUserOrgRep.Query(a => model.UserIds.Contains(a.UserId) && deleteOrgIds.Contains(a.OrgId)).DeleteFromQueryAsync();
            }

            if (insertOrgIds != null && insertOrgIds.Any())
            {
                var orgs = new List<sys_user_org>();
                foreach (var userId in model.UserIds)
                {
                    orgs.AddRange(insertOrgIds.Select(orgId => new sys_user_org
                    {
                        UserId = userId,
                        OrgId = orgId
                    }).ToList());
                }

                await SysUserOrgRep.AddRangeAsync(orgs);
            }

            var capPublisher = AppDependencyResolver.Current.GetRequiredService<ICapPublisher>();
            //发送部门转移
            var userOrgChangeEvent = model.Adapt<UserOrgChangeEvent>();
            await capPublisher.PublishAsync(GlobalConfig.SubscribeNames.UserOrgChange, userOrgChangeEvent);
        }

        /// <summary>
        /// 彻底删除用户
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns> 
        public virtual async Task DeleteAsync(long id)
        {
            var user = await SysUserRep.QueryNoTracking(e => e.Id == id).Select(e => new
            {
                e.Id,
                e.Type
            }).FirstOrDefaultAsync();
            if (user == null)
            {
                throw ServiceResult.Exception("用户不存在");
            }

            if (user.Type == UserType.PlatformAdmin)
            {
                throw ServiceResult.Exception("平台管理员禁止删除");
            }

            if (user.Type == UserType.TenantAdmin)
            {
                throw ServiceResult.Exception("企业管理员禁止删除");
            }

            //删除用户角色
            await SysUserRoleRep.QueryIgnoreQueryFilters(a => a.UserId == id).DeleteFromQueryAsync();
            //删除用户所属部门
            await SysUserOrgRep.QueryIgnoreQueryFilters(a => a.UserId == id).DeleteFromQueryAsync();
           
            //删除用户
            await SysUserRep.QueryIgnoreQueryFilters(a => a.Id == id).DeleteFromQueryAsync();

            //删除用户数据权限缓存
            await Cache.RemoveAsync(GlobalConfig.CacheKeys.GetDataPermissionPattern(id));
        }

        /// <summary>
        /// 批量彻底删除用户
        /// </summary>
        /// <param name="ids"></param>
        /// <returns></returns> 
        public virtual async Task BatchDeleteAsync(long[] ids)
        {
            var admin = await SysUserRep.QueryNoTracking(e => ids.Contains(e.Id) && (e.Type == UserType.PlatformAdmin || e.Type == UserType.TenantAdmin)).AnyAsync();

            if (admin)
            {
                throw ServiceResult.Exception("平台管理员禁止删除");
            }

            //删除用户角色
            await SysUserRoleRep.QueryIgnoreQueryFilters(a => ids.Contains(a.UserId)).DeleteFromQueryAsync();
            //删除用户所属部门
            await SysUserOrgRep.QueryIgnoreQueryFilters(a => ids.Contains(a.UserId)).DeleteFromQueryAsync(); 
            //删除用户
            await SysUserRep.QueryIgnoreQueryFilters(a => ids.Contains(a.Id)).DeleteFromQueryAsync();

            foreach (var userId in ids)
            {
                await Cache.RemoveAsync(GlobalConfig.CacheKeys.GetDataPermissionPattern(userId));
            }
        }

        /// <summary>
        /// 删除用户
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public virtual async Task SoftDeleteAsync(long id)
        {
            var user = await SysUserRep.QueryNoTracking(e => e.Id == id).Select(e => new
            {
                e.Id,
                e.Type
            }).FirstOrDefaultAsync();

            if (user == null)
            {
                throw ServiceResult.Exception("用户不存在");
            }

            if (user.Type == UserType.PlatformAdmin || user.Type == UserType.TenantAdmin)
            {
                throw ServiceResult.Exception("平台管理员禁止删除");
            } 
            await SysUserRep.Query(e => e.Id == id).DeleteFromQueryAsync();

            await Cache.RemoveAsync(GlobalConfig.CacheKeys.GetDataPermissionPattern(id));
        }

        /// <summary>
        /// 批量删除用户
        /// </summary>
        /// <param name="ids"></param>
        /// <returns></returns> 
        public virtual async Task BatchSoftDeleteAsync(long[] ids)
        {
            var admin = await SysUserRep.QueryNoTracking(e => ids.Contains(e.Id) &&
            (e.Type == UserType.PlatformAdmin || e.Type == UserType.TenantAdmin)).AnyAsync();

            if (admin)
            {
                throw ServiceResult.Exception("平台管理员禁止删除");
            }
             
            await SysUserRep.Query(e => ids.Contains(e.Id)).DeleteFromQueryAsync();

            foreach (var userId in ids)
            {
                await Cache.RemoveAsync(GlobalConfig.CacheKeys.GetDataPermissionPattern(userId));
            }
        }

        /// <summary>
        /// 上传头像
        /// </summary>
        /// <param name="file"></param>
        /// <param name="autoUpdate"></param>
        /// <returns></returns> 
        public async Task UpdateAvatar(SetStringDto model)
        {
            await SysUserRep.Query(e => model.Id == e.Id).UpdateFromQueryAsync(e => new sys_user()
            {
                Avatar = model.Value
            });
        }

        /// <summary>
        /// 一键登录用户
        /// </summary>
        /// <returns></returns> 
        public async Task<dynamic> OneClickLoginAsync(string account)
        {
            if (account.IsNotNullOrWhiteSpace())
            {
                throw ServiceResult.Exception("请选择用户");
            }

            var result = await SysUserRep.QueryNoTracking(e => e.Account == account).Select(e => new AuthLoginResultDto
            {
                Enabled = e.Enabled,
                Id = e.Id,
                Name = e.Name,
                OrgId = e.OrgId,
                TenantId = e.TenantId,
                Type = e.Type,
                Account = e.Account
            }).FirstOrDefaultAsync();


            if (result == null)
            {
                throw ServiceResult.Exception("用户不存在");
            }
             
            //string token = AppInfo.GetRequiredService<IAuthService>().GetToken(authLoginOutput);

            return new { string.Empty };
        }

        /// <summary>
        /// 强制用户下线
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public void ForceOfflineAsync(long id)
        {
            if (ImConfig.Enabled)
            {
                //推送消息
                ImHelper.SendMessage(0, [id], new
                {
                    evts = new[]
                    {
                    new { name = "forceOffline", data = new { } }
                }
                });

                //强制下线
                ImHelper.ForceOffline(id);
            }
            else
            {
                throw ServiceResult.Exception("请开启im即时通讯");
            }
        }
        #endregion

        #region private

        private async Task<Expression<Func<sys_user, bool>>> BuildSearch(QuerySysUserRequset model)
        {
            Expression<Func<sys_user, bool>> whereCondition = e => true;
            var dataPermission = User.DataPermission;
            if (dataPermission != null && dataPermission.OrgIds.Count() > 0)
            {
                var userIds = await SysUserOrgRep.QueryNoTracking(e => dataPermission.OrgIds.Contains(e.Id)).Select(e => e.UserId).ToListAsync();
                whereCondition = whereCondition.And(e => userIds.Contains(e.Id));
            }
            if (dataPermission != null && dataPermission.DataScope == DataScope.Self)
            {
                whereCondition = whereCondition.And(e => e.CreatorId == User.Id);
            }
            if (model.OrgId.HasValue)
            {
                var userIds = await SysUserOrgRep.QueryNoTracking(e => e.OrgId == model.OrgId).Select(e => e.UserId).ToListAsync();
                whereCondition = whereCondition.And(e => userIds.Contains(e.Id));
            }
            var orgIds = new List<long>();
            if (model.Key.IsNotNullOrWhiteSpace())
            {
                orgIds = await SysOrgRepLazy.Value.QueryNoTracking(e => e.Name.Contains(model.Key)).Select(e => e.Id).ToListAsync();
                whereCondition = whereCondition.And(e => orgIds.Contains(e.OrgId) || e.Account.Contains(model.Key));

            }



            if (model.SDate.HasValue)
                whereCondition = whereCondition.And(e => e.CreatedTime > model.SDate);
            if (model.EDate.HasValue)
            {
                var date = model.EDate.Value.AddDays(1);
                whereCondition = whereCondition.And(e => e.CreatedTime < date);
            }
            return whereCondition;
        }

        private Dictionary<Expression<Func<sys_user, dynamic>>, SortType> BuildSort(QuerySysUserRequset model)
        {
            var orderBy = new Dictionary<Expression<Func<sys_user, dynamic>>, SortType>();

            orderBy.Add(e => e.Id, SortType.Desc);
            return orderBy;
        }

        #endregion
    }
}

